﻿using System.Diagnostics;
using System.Windows.Input;
using Windows.UI.ApplicationSettings;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Media.Animation;

namespace Ebt.Mvvm
{
    /// <summary>
    /// This manager helps to show/hide panes in Settings charm
    /// </summary>
    public class SettingsCharmManager
    {
        private static Popup _popup;

        private const double WidePaneWidth = 646; // Desired width for the settings UI. UI guidelines specify this should be 346 or 646 depending on your needs.
        private const double NormalPaneWidth = 346; // Desired width for the settings UI. UI guidelines specify this should be 346 or 646 depending on your needs.

        static SettingsCharmManager()
        {
            Debug.WriteLine("SettingsCharmManager static ctor");
            GoBackCommand = new RelayCommand(OnGoBack);
        }

        /// <summary>
        /// This class is used as model to implement the Back button.
        /// </summary>
        public SettingsCharmManager()
        {
            Debug.WriteLine("SettingsCharmManager ctor");
        }

        /// <summary>
        /// Back button command
        /// </summary>
        public static ICommand GoBackCommand { get; private set; }

        private static void OnGoBack()
        {
            Debug.WriteLine("OnGoBack");

            ClosePane();

            // If the app is not snapped, then the back button shows the Settings pane again.
            if (Windows.UI.ViewManagement.ApplicationView.Value != Windows.UI.ViewManagement.ApplicationViewState.Snapped)
            {
                Debug.WriteLine("OnGoBack SettingsPane.Show");
                SettingsPane.Show();
            }
            Debug.WriteLine("OnGoBack end");
        }

        /// <summary>
        /// Show an UI control in SettingsPane
        /// </summary>
        /// <param name="pane">A UI control that represents pane</param>
        /// <param name="isWide">true to show wide pane</param>
        public static void ShowPane(FrameworkElement pane, bool isWide = false)
        {
            Debug.WriteLine("ShowPane before close");

            ClosePane();

            //define width
            var width = isWide ? WidePaneWidth : NormalPaneWidth;

            // Used to determine the correct height to ensure our custom UI fills the screen.
            var windowBounds = Window.Current.Bounds;

            // Create a Popup window which will contain our flyout.
            _popup = new Popup();
            _popup.Closed += OnPopupClosed;
            Window.Current.Activated += OnWindowActivated;
            _popup.IsLightDismissEnabled = true;
            _popup.Width = width;
            _popup.Height = windowBounds.Height;

            // Add the proper animation for the panel.
            _popup.ChildTransitions = new TransitionCollection { new EntranceThemeTransition() }; // Do not use PaneThemeTransition (and probably other) because it causes the application to crash on close of the popup with Win32 error.

            // Flyout the same dimenssions as the Popup.
            pane.Width = width;
            pane.Height = windowBounds.Height;

            // Place the SettingsFlyout inside our Popup window.
            _popup.Child = pane;

            // Let's define the location of our Popup.
            _popup.SetValue(Canvas.LeftProperty, SettingsPane.Edge == SettingsEdgeLocation.Right ? (windowBounds.Width - width) : 0);
            _popup.SetValue(Canvas.TopProperty, 0);
            _popup.IsOpen = true;

            Debug.WriteLine("ShowPane end");
        }

        /// <summary>
        /// Close a pane if it's open
        /// </summary>
        public static void ClosePane()
        {
            Debug.WriteLine("ClosePane start");
            if (_popup != null)
            {
                _popup.IsOpen = false;
                _popup = null;
                Debug.WriteLine("ClosePane middle");
            }
            Debug.WriteLine("ClosePane End");
        }

        private static void OnWindowActivated(object sender, WindowActivatedEventArgs e)
        {
            if (e.WindowActivationState == CoreWindowActivationState.Deactivated && _popup != null)
                ClosePane();
        }

        private static void OnPopupClosed(object sender, object e)
        {
            Window.Current.Activated -= OnWindowActivated;

            var popup = (Popup)sender;
            popup.Closed -= OnPopupClosed;
        }
    }
}
